using System;
using System.Collections.Generic;
using Microsoft.Office.Interop.Outlook;
using MSOffice = Microsoft.Office.Core;

namespace Office.Utility.Toolbar
{
    public abstract class CommandBar
    {
        private readonly CommandBarWindowType _windowType = CommandBarWindowType.ExplorersAndInspectors;

        public string Name { get; set; }

        private readonly List<WindowAdapter> _listWindows = new List<WindowAdapter>();
        internal IList<WindowAdapter> Windows
        {
            get { return _listWindows; }
        }

        public event EventHandler<BeforeShowCommandBarEventArgs> BeforeShow;

        protected void FireBeforeShow(BeforeShowCommandBarEventArgs args)
        {
            if (BeforeShow == null)
                return;

            BeforeShow(this, args);
        }

        internal void ShowCommandBar(WindowAdapter window, MSOffice.CommandBar bar)
        {
            var args = new BeforeShowCommandBarEventArgs(window, bar, true, true);
            FireBeforeShow(args);

            bar.Visible = args.Visible;
            bar.Enabled = true;

            //foreach (MSOffice.CommandBarControl ctl in bar.Controls)
            //{
            //    ctl.Enabled = args.Enabled;
            //}
        }

        protected CommandBar(string name)
        {
            Name = name;
        }

        protected CommandBar(string name, CommandBarWindowType windowType)
        {
            Name = name;
            _windowType = windowType;
        }

        /// <summary>
        /// Attach this toolbar to the specified explorer window
        /// </summary>
        /// <param name="explorer"></param>
        public void Attach(Explorer explorer)
        {
            if (_windowType == CommandBarWindowType.InspectorsOnly)
                return;

            //Newly created explorer windows (i.e. the parameter of the NewExplorer event) throw an exception
            //if you attempt to access their commandbars collection. The CommandBars property of the WindowAdapter
            //class swallows that exception and returns null instead. If the explorer window is new and the commandbars
            //collection isn't accessable, subscribe to the acitvate event and bind the toolbar there. Otherwise, bind 
            //the toolbar now.

            var window = new WindowAdapter(explorer);
            if (window.CommandBars != null)
            {
                DoAttach(window);
            }
            else
            {
                EventHandler onActivate = null;
                onActivate = delegate(object sender, EventArgs e)
                {
                    // ReSharper disable AccessToModifiedClosure
                    window.Activate -= onActivate;
                    // ReSharper restore AccessToModifiedClosure
                    DoAttach(window);
                };
                window.Activate += onActivate;
            }
        }

        /// <summary>
        /// Attach this toolbar to the specified inspector window
        /// </summary>
        public void Attach(Inspector inspector)
        {
            if (_windowType == CommandBarWindowType.ExplorersOnly)
                return;

            var window = new WindowAdapter(inspector);
            DoAttach(window);
        }

        private void DoAttach(WindowAdapter window)
        {
            window.Close += ((sender, args) => Detach(window));

            Attach(window);
        }

        internal abstract void Attach(WindowAdapter window);
        internal abstract void Detach(WindowAdapter window);

    }
}
